package org.groupg.practice;

import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;

import java.util.*;
import java.util.concurrent.*;

/**
 * 代码有问题。 forkjoin 的用法有问题，应该是通过图的依赖节点
 */
public class ForkJoinGraphExample {

    // 定义一个任务，处理图中的一个节点
    static class NodeTask extends RecursiveTask<Integer> {
        private final String nodeName;
        private final Map<String, Integer> sharedMemory; // 模拟共享内存
        private final Graph<String, DefaultEdge> graph;

        public NodeTask(String nodeName, Map<String, Integer> sharedMemory, Graph<String, DefaultEdge> graph) {
            this.nodeName = nodeName;
            this.sharedMemory = sharedMemory;
            this.graph = graph;
        }

        @Override
        protected Integer compute() {
            // 模拟对节点的处理，假设返回一个整数值
            int result = processNode(nodeName);

            // 将结果写入共享内存
            sharedMemory.put(nodeName, result);

            // 如果有依赖任务（例如，处理相邻节点），可以在这里创建子任务
            List<NodeTask> subTasks = new ArrayList<>();
            for (String neighbor : graph.vertexSet().stream()
                    .filter(v -> graph.containsEdge(nodeName, v))
                    .toList()) {
                // 仅当邻居节点尚未处理时才创建任务
                if (!sharedMemory.containsKey(neighbor)) {
                    subTasks.add(new NodeTask(neighbor, sharedMemory, graph));
                }
                System.out.println("Node " + nodeName + " has shared memory " + sharedMemory.get(neighbor));
            }

            // 并行执行子任务并合并结果（这里简单求和）
            if (subTasks.isEmpty()) {
                return result;
            } else {
                return subTasks.parallelStream()
                        .mapToInt(ForkJoinTask::join) // 并行执行并获取结果
                        .sum() + result; // 合并结果
            }
        }

        // 模拟节点处理逻辑
        private int processNode(String nodeName) {
            System.out.println("Processing node " + nodeName);
            // 这里可以是任何复杂的计算逻辑
            return nodeName.hashCode() % 10; // 简单示例：返回节点名称的哈希码的个位数
        }
    }

    public static void main(String[] args) {
        // 创建一个有向图
        Graph<String, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);

        // 添加顶点和边
        graph.addVertex("a");
        graph.addVertex("b");
        graph.addVertex("c");
        graph.addVertex("d");
        graph.addEdge("a", "b");
        graph.addEdge("b", "c");
        graph.addEdge("a", "c");
        graph.addEdge("c", "d");

        // 共享内存，用于存储节点处理结果
        Map<String, Integer> sharedMemory = new ConcurrentHashMap<>();

        // 创建一个 ForkJoinPool
        ForkJoinPool forkJoinPool = new ForkJoinPool();

        // 从某个节点开始处理（假设从 "a" 开始）
        NodeTask rootTask = new NodeTask("d", sharedMemory, graph);

        // 提交任务并获取结果
        int totalResult = forkJoinPool.invoke(rootTask);

        // 输出结果
        System.out.println("Total result: " + totalResult);
        System.out.println("Shared memory: " + sharedMemory);
    }
}
